/*
@STI LICENSE
(C) 2006-2008 Universit�t Innsbruck.

This file is part of myOntology.

myOntologyis free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

myOntologyis distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with myOntology.  If not, see <http://www.gnu.org/licenses/>.

@STI LICENSE */
package controller.sesameDataConnector;

import model.Vocabulary;
import model.dataContainer.UserContainer;

import org.apache.log4j.Logger;
import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.impl.LiteralImpl;
import org.openrdf.model.impl.URIImpl;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.RepositoryResult;

public class UserConnector {

public static Logger logger = Logger.getLogger(UserConnector.class);
	
	public static URI insert(UserContainer user) throws ControllerException {
	
		URI id = new URIImpl(Vocabulary.USER_NAMESPACE + user.getUserid());
		try {
			
			RepositoryConnection con = AbstractDataConnector.getConnection();
			
			try {
				
				RepositoryResult<Statement> statements = con.getStatements(id, null, null, false);
				try {
					if (statements.hasNext()) {
						throw new ControllerException("User " + user.getUserid() + " exists already!");
					}	
				} finally {
					statements.close();
				}
				
				con.add(id, RDF.TYPE, Vocabulary.USER);
				con.add(id, Vocabulary.HASFIRSTNAME, new LiteralImpl(user.getFirst_name()));
				con.add(id, Vocabulary.HASLASTNAME, new LiteralImpl(user.getLast_name()));
				con.add(id, Vocabulary.HASEMAIL, new LiteralImpl(user.getE_mail()));
				con.add(id, Vocabulary.HASADDRESS, new LiteralImpl(user.getAddress()));
				con.add(id, Vocabulary.HASPWD, new LiteralImpl(user.getPwd()));
				
				con.commit();
			} catch( Exception e ) {
				con.rollback();	
				throw e;
			} finally {
				con.close();
			}
			
		} catch (Exception e){
			logger.error(e);
			if (e instanceof ControllerException)
				throw (ControllerException) e;
		}
			
		return id;
	}
	
	
	public static boolean try_login(String userid, String pwd, String sessionId) {
		boolean ret = false;
		
		try {	
			RepositoryConnection con = AbstractDataConnector.getConnection();

			URI id = new URIImpl(Vocabulary.USER_NAMESPACE + userid);
			try {
				

				RepositoryResult<Statement> statements = con.getStatements(id, Vocabulary.HASPWD, null, false);
				try {

					if (statements.hasNext() ) {
						
						if( statements.next().getObject().equals( new LiteralImpl( pwd ) ) ) {
							statements.close();
						
							con.remove( id, Vocabulary.HASSESSIONID, null );
							con.add(id, Vocabulary.HASSESSIONID, new LiteralImpl(sessionId));
							
							ret = true;						
						}
					}	
					
				}
				catch( Exception e ) {
					throw e;
				}
				finally {
					statements.close();
				}
				
				con.commit();
			} catch( Exception e ) {
				con.rollback();	
				throw e;
			} finally {
				con.close();
			}
		} catch (Exception e) {
			logger.error(e);
		}

		return ret;	
	}
	
	public static URI is_loged_on(String sessionId) {
		URI ret = null;

		try {	
			RepositoryConnection con = AbstractDataConnector.getConnection();

			try {
	
				RepositoryResult<Statement> statements = con.getStatements(null, Vocabulary.HASSESSIONID, new LiteralImpl( sessionId ), false);
				try {
					if (statements.hasNext()) {
						ret = (URI)statements.next().getSubject();
					}	
				} finally {
					statements.close();
				}
				
				
			} finally {
				con.close();
			}
		} catch (Exception e) {
			logger.error(e);
		}
		return ret;	
	}	
	
	
	public static String getUserInfo(URI id){
		String ret ="";
		try {
			RepositoryConnection con = AbstractDataConnector.getConnection();
			
			try {

				RepositoryResult<Statement> statements = con.getStatements(id, Vocabulary.HASFIRSTNAME, null, false);
				try {
					if (statements.hasNext()) {
						Statement st = statements.next();
						ret += st.getObject().stringValue();
					}	
				} finally {
					statements.close();
				}
				
				statements = con.getStatements(id, Vocabulary.HASLASTNAME, null, false);
				try {
					if (statements.hasNext()) {
						Statement st = statements.next();
						ret += " " + st.getObject().stringValue();
					}	
				} finally {
					statements.close();
				}
				
			} finally {
				con.close();
			}
		} catch (Exception e) {
			logger.error(e);
		}
		return ret;	
	}
	
	
	
	public static boolean logout (String sessionID) {
		
		//URI id = new URIImpl(Vocabulary.USER_NAMESPACE + userid);
		
		try {	
			RepositoryConnection con = AbstractDataConnector.getConnection();
			
			try {
				con.remove(null, Vocabulary.HASSESSIONID, new LiteralImpl(sessionID));
				
				con.commit();
			} catch( Exception e ) {
				con.rollback();	
				throw e;
			} finally {
				con.close();
			}
		} catch (Exception e) {
			logger.error(e);
			return false;
		}
		return true;	
	}	
	
	
	public static UserContainer select(String sessionID) {
		UserContainer user = new UserContainer();
		URI id;
		Statement st;
		
		try {
			RepositoryConnection con = AbstractDataConnector.getConnection();
			
			try {
				RepositoryResult<Statement> statements = con.getStatements(null, Vocabulary.HASSESSIONID, new LiteralImpl(sessionID), false);
				try {
					if (statements.hasNext()) {
						st = statements.next();
						id = new URIImpl(st.getSubject().stringValue());
						user.setUserid(id.getLocalName());
					}	
					else {
						return null;
					}
					
					statements = con.getStatements(id, Vocabulary.HASFIRSTNAME, null, false);
					if (statements.hasNext()) {
						st = statements.next();
						user.setFirst_name(st.getObject().stringValue());
					}
					
					statements = con.getStatements(id, Vocabulary.HASLASTNAME, null, false);
					if (statements.hasNext()) {
						st = statements.next();
						user.setLast_name(st.getObject().stringValue());
					}
					
					statements = con.getStatements(id, Vocabulary.HASEMAIL, null, false);
					if (statements.hasNext()) {
						st = statements.next();
						user.setE_mail(st.getObject().stringValue());
					}
					
					statements = con.getStatements(id, Vocabulary.HASADDRESS, null, false);
					if (statements.hasNext()) {
						st = statements.next();
						user.setAddress(st.getObject().stringValue());
					}
					
					statements = con.getStatements(id, Vocabulary.HASPWD, null, false);
					if (statements.hasNext()) {
						st = statements.next();
						user.setPwd(st.getObject().stringValue());
					}
				
				} finally {
					statements.close();			
				}
				
			}finally {
				con.close();
			}
		} catch (Exception e) {
			logger.error(e);
			return null;
		}
		
		return user;
	}
	
	public static boolean update(UserContainer user) {
		
		URI id = new URIImpl(Vocabulary.USER_NAMESPACE + user.getUserid());
		
		try {
			RepositoryConnection con = AbstractDataConnector.getConnection();
			try {
				//delete old data
				con.remove(id, Vocabulary.HASFIRSTNAME, null);
				con.remove(id, Vocabulary.HASLASTNAME, null);
				con.remove(id, Vocabulary.HASADDRESS, null);
				con.remove(id, Vocabulary.HASEMAIL, null);
				con.remove(id, Vocabulary.HASPWD, null);
				
				//insert new data
				con.add(id, Vocabulary.HASFIRSTNAME, new LiteralImpl(user.getFirst_name()));
				con.add(id, Vocabulary.HASLASTNAME, new LiteralImpl(user.getLast_name()));
				con.add(id, Vocabulary.HASEMAIL, new LiteralImpl(user.getE_mail()));
				con.add(id, Vocabulary.HASADDRESS, new LiteralImpl(user.getAddress()));
				con.add(id, Vocabulary.HASPWD, new LiteralImpl(user.getPwd()));

				
				con.commit();
			} catch( Exception e ) {
				con.rollback();	
				throw e;
			}finally {
				con.close();
			}
		} catch (Exception e) {
			logger.error(e);
			return false;
		}
		return true;
	}
	
}
